Reactive Programming 概念上與Observer Pattern非常相似,先來了解這個Design Pattern。
Observer Pattern
會有兩種角色,一種是subject
主體,是我們感興趣的目標,另一種是observers
觀察者,觀察者選擇了各種感興趣的主題去關注,當主題的狀態發生變化的時候就會通知觀察者。
生活中有很多例子,以前的送報紙,訂報紙的人就是觀察者,想了解新聞,所以報紙就會派發到家裡。Youtube或是Twitch上的訂閱制,使用者就是觀察者,對哪一個實況主或是頻道有興趣,就點選訂閱,當實況主開啟直播、Youtuber發布新影片,就會有通知送達使用者,如果不使用Observer Pattern
,使用者如果想要知道有沒有新影片,就必須要時不時的去查看是否有更新,這還是用電腦,如果是想去看店家缺貨已久的PS5遊戲機是否已到貨,若沒有觀察者模式可以訂閱通知,則必須要出家門到店裡面才能得知。
實際設計一個簡單的例子
Subject與Observer的Interface,定義出基本的訂閱、取消訂閱、通知與更新的方法。
public interface Subject {
void subscribe(Observer observer);
void unsubscribe(Observer observer);
void notifyObservers();
}
public interface Observer {
void update(String name);
}
實作使用者與YotubeChannel類別,更新狀態印出頻道名稱。頻道紀錄訂閱者與頻道名稱,訂閱決定是否放入訂閱者名單當中,更新時會通知所有訂閱者。
public class User implements Observer{
@Override
public void update(String name) {
System.out.println(name + "更新囉");
}
}
@Data
@NoArgsConstructor
public class YoutubeChannel implements Subject{
private String name;
private List<Observer> users;
public YoutubeChannel(String name) {
this.name = name;
users = new ArrayList<>();
}
@Override
public void subscribe(Observer observer) {
users.add(observer);
}
@Override
public void unsubscribe(Observer observer) {
users.remove(observer);
}
@Override
public void notifyObservers() {
users.forEach(user -> user.update(name));
}
}
最後執行測試,創立一個User並訂閱兩個頻道,當兩個頻道更新時就可以看見通知,而取消訂閱CS50後就只會通知一個。
@Test
void test() {
User user = new User();
YoutubeChannel cs50 = new YoutubeChannel("CS50");
YoutubeChannel springDevelop = new YoutubeChannel("SpringDevelop");
cs50.subscribe(user);
springDevelop.subscribe(user);
cs50.notifyObservers();
springDevelop.notifyObservers();
cs50.unsubscribe(user);
cs50.notifyObservers();
springDevelop.notifyObservers();
/*
output:
CS50更新囉
SpringDevelop更新囉
SpringDevelop更新囉
*/
}
如果你已經了解Event-driven
,應該會覺得十分熟悉,只是Event-driven
通常中間會有一個Queue但是Observer Pattern
則不一定。了解Observer Pattern
之後下一篇就要開始真正進入Reactive Programming,會先從Java 9開始了解。